www.gusucode.com > VC++ Flash(SWF)文件创建生成Lib库源码+demo-源码程序 > VC++ Flash(SWF)文件创建生成Lib库源码+demo-源码程序/code/SWFLIB_Library/SWFMatrix.cpp

    // SWFMatrix.cpp: implementation of the CSWFMatrix class.
//
//////////////////////////////////////////////////////////////////////

#include "SWFMatrix.h"


CSWFMatrix::CSWFMatrix()
{
	// Init members
	m_SWFStream = NULL;
	m_SWFStreamLength = 0;
	m_SWFMatrix.MatrixFlags = 0;
	m_SWFMatrix.NScaleBits = m_SWFMatrix.NRotateBits = m_SWFMatrix.NTranslateBits = 0;
	m_SWFMatrix.ScaleX = m_SWFMatrix.ScaleY = 0;
	m_SWFMatrix.RotateSkew0 = m_SWFMatrix.RotateSkew1 = 0;
	m_SWFMatrix.TranslateX = m_SWFMatrix.TranslateY = 0;
	memset(&m_Matrix, 0, sizeof(MATRIX_F));
}

CSWFMatrix::~CSWFMatrix()
{
	if (m_SWFStream != NULL)
	{
		delete m_SWFStream;
		m_SWFStream = NULL;
	}
}

void CSWFMatrix::SetMatrix(MATRIX_F matrix)
{
	// Copy transformation matrix
	memcpy(&m_Matrix, &matrix, sizeof(MATRIX_F));

	// If matrix has scaling
	if ((matrix.scaleX != 0) || (matrix.scaleY != 0))
	{
		ULONG scaleX = (ULONG)(matrix.scaleX * 65536);
		ULONG scaleY = (ULONG)(matrix.scaleY * 65536);

		int maxValue = __max((int)matrix.scaleX, (int)matrix.scaleY);
		UCHAR scaleBitsNeaded = 0;
		// Calculate scale-bits neaded
		while (pow(2, scaleBitsNeaded) < maxValue)
			scaleBitsNeaded++;
		scaleBitsNeaded += 17;

		m_SWFMatrix.MatrixFlags |= 0x04;
		m_SWFMatrix.NScaleBits = scaleBitsNeaded;
		m_SWFMatrix.ScaleX = MAKELONG(LOWORD(scaleX), HIWORD(scaleX));
		m_SWFMatrix.ScaleY = MAKELONG(LOWORD(scaleY), HIWORD(scaleY));
	}

	// If matrix has rotation
	if ((matrix.rotateSkew0 != 0) || (matrix.rotateSkew1 != 0))
	{
		ULONG rotateSkew0 = (ULONG)(matrix.rotateSkew0 * 65536);
		ULONG rotateSkew1 = (ULONG)(matrix.rotateSkew1 * 65536);

		int maxValue = __max((int)matrix.rotateSkew0, (int)matrix.rotateSkew1);
		UCHAR rotateSkewBitsNeaded = 0;
		// Calculate rotate-skew-bits neaded
		while (pow(2, rotateSkewBitsNeaded) < maxValue)
			rotateSkewBitsNeaded++;
		rotateSkewBitsNeaded += 17;

		m_SWFMatrix.MatrixFlags |= 0x02;
		m_SWFMatrix.NRotateBits = rotateSkewBitsNeaded;
		m_SWFMatrix.RotateSkew0 = MAKELONG(LOWORD(rotateSkew0), HIWORD(rotateSkew0));
		m_SWFMatrix.RotateSkew1 = MAKELONG(LOWORD(rotateSkew1), HIWORD(rotateSkew1));
	}

	// If matrix has translation
	if ((matrix.translateX != 0) || (matrix.translateY != 0))
	{
		m_SWFMatrix.MatrixFlags |= 0x01;
		m_SWFMatrix.TranslateX = (int)(matrix.translateX * 20);
		m_SWFMatrix.TranslateY = (int)(matrix.translateY * 20);

		int maxValue = __max(abs(m_SWFMatrix.TranslateX), abs(m_SWFMatrix.TranslateY));
		UCHAR translateBitsNeaded = 0;
		// Calculate translate-bits neaded
		while (pow(2, translateBitsNeaded) < maxValue)
			translateBitsNeaded++;
		translateBitsNeaded++;

		m_SWFMatrix.NTranslateBits = translateBitsNeaded;
	}
}

void CSWFMatrix::GetMatrix(MATRIX_F& matrix)
{
	// Copy transformation matrix
	memcpy(&matrix, &m_Matrix, sizeof(MATRIX_F));
}

UCHAR* CSWFMatrix::BuildSWFStream()
{
	UCHAR bitsNeaded = 2;
	int byteIndex=0, bitOffset=0, i;

	// Calculate total bits neaded
	if (m_SWFMatrix.MatrixFlags & 0x04)
		bitsNeaded += (5 + 2*m_SWFMatrix.NScaleBits);
	if (m_SWFMatrix.MatrixFlags & 0x02)
		bitsNeaded += (5 + 2*m_SWFMatrix.NRotateBits);
	bitsNeaded += (5 + 2*m_SWFMatrix.NTranslateBits);

	// Create byte field
	m_SWFStreamLength = bitsNeaded / 8;
	if ((bitsNeaded%8) != 0)
		m_SWFStreamLength++;
	if (m_SWFStream != NULL)
		delete m_SWFStream;
	m_SWFStream = new UCHAR[m_SWFStreamLength];
	memset(m_SWFStream, 0, m_SWFStreamLength);

	// Write scale bit-field to .SWF stream
	if (m_SWFMatrix.MatrixFlags & 0x04)
	{
		m_SWFStream[byteIndex] |= 0x80;
		bitOffset++;

		// Write nScaleBits bit-field to .SWF stream
		UCHAR nScaleBits = m_SWFMatrix.NScaleBits << 3;
		UCHAR maskNScaleBits = 0x80;
		for (i=0; i<5; i++)
		{
			m_SWFStream[byteIndex] |= (((nScaleBits & maskNScaleBits) >> (7-i)) << ((byteIndex+1)*8-bitOffset-1));

			bitOffset++;
			if ((bitOffset != 0) && (bitOffset % 8) == 0)
				byteIndex++;

			maskNScaleBits = maskNScaleBits >> 1;
		}

		// Write scaleX bit-field to .SWF stream
		ULONG scaleX = m_SWFMatrix.ScaleX << (32-m_SWFMatrix.NScaleBits);
		ULONG maskScaleX = 0x80000000;
		for (i=0; i<m_SWFMatrix.NScaleBits; i++)
		{
			m_SWFStream[byteIndex] |= (((scaleX & maskScaleX) >> (31-i)) << ((byteIndex+1)*8-bitOffset-1));

			bitOffset++;
			if ((bitOffset != 0) && (bitOffset % 8) == 0)
				byteIndex++;

			maskScaleX = maskScaleX >> 1;
		}

		// Write scaleY bit-field to .SWF stream
		ULONG scaleY = m_SWFMatrix.ScaleY << (32-m_SWFMatrix.NScaleBits);
		ULONG maskScaleY = 0x80000000;
		for (i=0; i<m_SWFMatrix.NScaleBits; i++)
		{
			m_SWFStream[byteIndex] |= (((scaleY & maskScaleY) >> (31-i)) << ((byteIndex+1)*8-bitOffset-1));

			bitOffset++;
			if ((bitOffset != 0) && (bitOffset % 8) == 0)
				byteIndex++;

			maskScaleY = maskScaleY >> 1;
		}
	}
	else
		bitOffset++;

	// Write rotate bit-field to .SWF stream
	if (m_SWFMatrix.MatrixFlags & 0x02)
	{
		// Write rotateFlag to .SWF stream
		m_SWFStream[byteIndex] |= (0x01 << ((byteIndex+1)*8-bitOffset-1));
		bitOffset++;
		if ((bitOffset != 0) && (bitOffset % 8) == 0)
			byteIndex++;

		// Write nRotateBits bit-field to .SWF stream
		UCHAR nRotateBits = m_SWFMatrix.NRotateBits << 3;
		UCHAR maskNRotateBits = 0x80;
		for (i=0; i<5; i++)
		{
			m_SWFStream[byteIndex] |= (((nRotateBits & maskNRotateBits) >> (7-i)) << ((byteIndex+1)*8-bitOffset-1));

			bitOffset++;
			if ((bitOffset != 0) && (bitOffset % 8) == 0)
				byteIndex++;

			maskNRotateBits = maskNRotateBits >> 1;
		}

		// Write rotateSkew0 bit-field to .SWF stream
		ULONG rotateSkew0 = m_SWFMatrix.RotateSkew0 << (32-m_SWFMatrix.NRotateBits);
		ULONG maskRotateSkew0 = 0x80000000;
		for (i=0; i<m_SWFMatrix.NRotateBits; i++)
		{
			m_SWFStream[byteIndex] |= (((rotateSkew0 & maskRotateSkew0) >> (31-i)) << ((byteIndex+1)*8-bitOffset-1));

			bitOffset++;
			if ((bitOffset != 0) && (bitOffset % 8) == 0)
				byteIndex++;

			maskRotateSkew0 = maskRotateSkew0 >> 1;
		}

		// Write rotateSkew1 bit-field to .SWF stream
		ULONG rotateSkew1 = m_SWFMatrix.RotateSkew1 << (32-m_SWFMatrix.NRotateBits);
		ULONG maskRotateSkew1 = 0x80000000;
		for (i=0; i<m_SWFMatrix.NRotateBits; i++)
		{
			m_SWFStream[byteIndex] |= (((rotateSkew1 & maskRotateSkew1) >> (31-i)) << ((byteIndex+1)*8-bitOffset-1));

			bitOffset++;
			if ((bitOffset != 0) && (bitOffset % 8) == 0)
				byteIndex++;

			maskRotateSkew1 = maskRotateSkew1 >> 1;
		}
	}
	else
	{
		bitOffset++;
		if ((bitOffset != 0) && (bitOffset % 8) == 0)
			byteIndex++;
	}

	// Write nTranslateBits bit-field to .SWF stream
	UCHAR nTranslateBits = m_SWFMatrix.NTranslateBits << 3;
	UCHAR maskNTranslateBits = 0x80;
	for (i=0; i<5; i++)
	{
		m_SWFStream[byteIndex] |= (((nTranslateBits & maskNTranslateBits) >> (7-i)) << ((byteIndex+1)*8-bitOffset-1));

		bitOffset++;
		if ((bitOffset != 0) && (bitOffset % 8) == 0)
			byteIndex++;

		maskNTranslateBits = maskNTranslateBits >> 1;
	}

	// Write translateX bit-field to .SWF stream
	ULONG translateX = m_SWFMatrix.TranslateX << (32-m_SWFMatrix.NTranslateBits);
	ULONG maskTranslateX = 0x80000000;
	for (i=0; i<m_SWFMatrix.NTranslateBits; i++)
	{
		m_SWFStream[byteIndex] |= (((translateX & maskTranslateX) >> (31-i)) << ((byteIndex+1)*8-bitOffset-1));

		bitOffset++;
		if ((bitOffset != 0) && (bitOffset % 8) == 0)
			byteIndex++;

		maskTranslateX = maskTranslateX >> 1;
	}

	// Write translateY bit-field to .SWF stream
	ULONG translateY = m_SWFMatrix.TranslateY << (32-m_SWFMatrix.NTranslateBits);
	ULONG maskTranslateY = 0x80000000;
	for (i=0; i<m_SWFMatrix.NTranslateBits; i++)
	{
		m_SWFStream[byteIndex] |= (((translateY & maskTranslateY) >> (31-i)) << ((byteIndex+1)*8-bitOffset-1));

		bitOffset++;
		if ((bitOffset != 0) && (bitOffset % 8) == 0)
			byteIndex++;

		maskTranslateY = maskTranslateY >> 1;
	}

	return m_SWFStream;
}

int CSWFMatrix::GetSWFStreamLength()
{
	return m_SWFStreamLength;
}